package it.lupo.core.gui.controller;

import it.lupo.core.LupoSession;
import it.lupo.core.Util;
import it.lupo.core.gui.MainApp;
import it.lupo.core.gui.widget.DatePropertyValueFactory;
import it.lupo.core.gui.widget.LimitedTextField;
import it.lupo.model.BarCode;
import it.lupo.model.User;
import it.lupo.model.service.BarCodeService;
import it.lupo.model.service.SearchService;

import java.net.URL;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;

import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.DatePicker;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;


public class SearchController implements Initializable {

	public static final String FXML_FILE = "src/main/resources/search.fxml";


	private static final int INIT_MAX_RESULTS = 25;
	
	
	private Long id;
	@FXML
	private TextField code;
	@FXML
	private LimitedTextField cod_fisc;
	@FXML
	private TextField name;
	@FXML
	private TextField surname;
	@FXML
	private TextField email;	
	@FXML
	private TextField address;
	@FXML
	private TextField operator;
	@FXML
	private DatePicker birthday;
	@FXML
	private Button b_search,b_save,b_add,b_cancel;
	
	
	@FXML
	private TableView<BarCode> table;
	@FXML
	private TableColumn<BarCode, String> barcodeColumn;
	@FXML
	private TableColumn<BarCode, String> addressColumn;
	@FXML
	private TableColumn<BarCode, String> cfColumn;
	@FXML
	private TableColumn<BarCode, String> emailColumn;
	@FXML
	private TableColumn<BarCode, String> nameColumn;
	@FXML
	private TableColumn<BarCode, String> surnameColumn;
	@FXML
	private TableColumn<BarCode, String> operatorColumn;
	@FXML
	private TableColumn<BarCode, String> dateColumn;
	@FXML
	private TableColumn<BarCode, String> birthdayColumn;
	
	
	private ObservableList<BarCode> results;
	
	private SearchService service; 
	private BarCodeService bservice;
	
	@FXML
	public void onSearch()
	{
		String barcode = cleanValue(code.getText());
		String cf = cleanValue(cod_fisc.getText());
		String address = cleanValue(this.address.getText());
		String email = cleanValue(this.email.getText());
		String name = cleanValue(this.name.getText());
		String surname = cleanValue(this.surname.getText());
		List<BarCode> list = service.search(barcode, cf, address, email, name, surname);
		System.out.println("RESULTS = "+list.size());
		results.clear();
		if(list!=null)
			results.addAll(list);
	}

	@FXML
	@Override
	public void initialize(URL arg0, ResourceBundle arg1) {
		
		
		service = SearchService.getInstance();
		bservice = BarCodeService.getInstance();
		
		results = FXCollections.observableArrayList();
		barcodeColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("barcode"));
		addressColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("address"));
		cfColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("CF"));
		nameColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("name"));
		surnameColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("surname"));
		emailColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("email"));
		operatorColumn.setCellValueFactory(new PropertyValueFactory<BarCode, String>("operatorid"));
		birthdayColumn.setCellValueFactory(new DatePropertyValueFactory<BarCode, String>("birthday"));
//		PropertyValueFactory p = new PropertyValueFactory<BarCode, DateProperty>("registration") ;
		
		dateColumn.setCellValueFactory(new DatePropertyValueFactory<BarCode, String>("registration"));
		

		initTable();
		
		table.setItems(results);
		table.setRowFactory(
		    new Callback<TableView<BarCode>, TableRow<BarCode>>() {
		    	  @Override
		    	  public TableRow<BarCode> call(TableView<BarCode> tableView) {
		    		  
		    		  
		    		  
		    		  
		    	    final TableRow<BarCode> row = new TableRow<>();
		    	    final ContextMenu rowMenu = new ContextMenu();
		    	   
//					tableView.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>()
//							{
//						  		@Override
//					        	public void handle(MouseEvent t) {
////						  			 TableCell c = (TableCell) t.getSource();
////						             int index = 0;t.getSource();
//						             System.out.println(t+" "+t.getSource().getClass());
////						             BarCode selected = results.get(index);
////						             toConferment(selected);
//						             
//						  		}
//							});
		    	    
//		    	    TASTO DESTRO 
		    	    
		    	    MenuItem removeItem = new MenuItem("Cancella");
		    	    removeItem.setOnAction(new EventHandler<ActionEvent>() {
		    	      @Override
		    	      public void handle(ActionEvent event) {
		    	    	  toDelete(row.getItem());
		    	      }					
		    	    });
		    	    
		    	    MenuItem editItem = new MenuItem("Modifica");
		    	    editItem.setOnAction(new EventHandler<ActionEvent>() {
		    	      @Override
		    	      public void handle(ActionEvent event) {
		    	    	  toEdit(row.getItem());
		    	      }
		    	    });
		    	    
		    	    
		    	    MenuItem confermentItem = new MenuItem("Conferisci");
		    	    confermentItem.setOnAction(new EventHandler<ActionEvent>() {
		    	      @Override
		    	      public void handle(ActionEvent event) {		    	    	  
							toConferment(row.getItem());
		    	      }
		    	    });
		    	    
		    	    
		    	    
		    	    
		    	    rowMenu.getItems().addAll(confermentItem,editItem,removeItem);

		    	    // only display context menu for non-null items:
		    	    row.contextMenuProperty().bind(
		    	      Bindings.when(Bindings.isNotNull(row.itemProperty()))
		    	      .then(rowMenu)
		    	      .otherwise((ContextMenu)null));
		    	    
		    	    
		    	    
		    	    return row;
		    	  }
		    	});
		
		
		
		
		
		
		onCancel();
	}
	
	private void initTable()
	{
		results.clear();
		results.addAll(bservice.getLasts(INIT_MAX_RESULTS));
	}
	
	
	private void toConferment(BarCode bcode) 
	{
		LupoSession session = LupoSession.getCurrent();
		session.setBarcodeSession(bcode);
		try {
			MainApp.getInstance().change(HomeController.FXML_FILE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void toEdit(BarCode bcode)
	{
		id = bcode.getId();
		code.setText(bcode.getBarcode());		
		cod_fisc.setText(bcode.getCF());
		name.setText(bcode.getName());
		surname.setText(bcode.getSurname());
		email.setText(bcode.getEmail());	
		address.setText(bcode.getAddress());
		address.setText(bcode.getAddress());
		operator.setText(bcode.getOperator().getId());
		operator.setDisable(true); 
		
		 
		
		birthday.setValue( Util.dateToLocalDate(bcode.getBirthday()));
		
		b_search.setDisable(true);
		b_add.setDisable(true);
		b_save.setDisable(false);
		b_cancel.setDisable(false);
	}
	
	private void toDelete(BarCode item) {
		bservice.delete(item);
		initTable();
		onCancel();
	}
		
	@FXML
	private void onCancel()
	{
		id = null;
		code.setText(null);		
		cod_fisc.setText(null);
		name.setText(null);
		surname.setText(null);
		email.setText(null);	
		address.setText(null);
		operator.setText(LupoSession.getCurrent().getUser().getId());
		operator.setDisable(true);
		birthday.setValue(null);
		
		b_search.setDisable(false);
		b_add.setDisable(false);
		b_save.setDisable(true);
		b_cancel.setDisable(true);
		
	}
	@FXML
	private void onAdd()
	{
		id = null;
		b_search.setDisable(true);
		b_add.setDisable(true);
		b_save.setDisable(false);
		b_cancel.setDisable(false);
	}
	@FXML
	private void onSave()
	{
		User u = LupoSession.getCurrent().getUser();
		BarCode b = new BarCode(
				id, code.getText(), 
				cod_fisc.getText(), name.getText(), 
				surname.getText(),
				email.getText(),
				address.getText(), 
				null, // comments 
				true,
				new Date(),Util.localDateToDate(birthday.getValue()),u);		 
		//TODO mettere i controlli
		if(id==null) //add
			bservice.create(b);
		else
			bservice.update(b);
		
//		onSearch();
		initTable();
		onCancel();
	}
	
	
	
	@FXML
	public void close()
	{
		try {
			MainApp.getInstance().change(BarCodeController.FXML_FILE);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private String cleanValue(String obj)
	{
		return (obj!=null && !obj.trim().isEmpty())?obj:null;
	}
	
	
}

